home *** CD-ROM | disk | FTP | other *** search
/ Libris Britannia 4 / science library(b).zip / science library(b) / ASTRONOM / H139.ZIP / UI101.ZIP / IO / GR / GR_X.C < prev    next >
C/C++ Source or Header  |  1991-11-04  |  31KB  |  1,163 lines

  1. /****************************************************************
  2.  
  3.     gr_x.c        X Windows Implementation
  4.             of Bywater Graphics Interface Standard
  5.  
  6.             Tested on DecStation 2100 and 3100
  7.  
  8.             Copyright (c) 1991, Ted A. Campbell
  9.  
  10.             Bywater Software
  11.             P. O. Box 4023 
  12.             Duke Station 
  13.             Durham, NC  27706
  14.  
  15.             email: tcamp@hercules.acpub.duke.edu
  16.  
  17.     Copyright and Permissions Information:
  18.  
  19.     All U.S. and international copyrights are claimed by the
  20.     author. The author grants permission to use this code
  21.     and software based on it under the following conditions:
  22.     (a) in general, the code and software based upon it may be 
  23.     used by individuals and by non-profit organizations; (b) it
  24.     may also be utilized by governmental agencies in any country,
  25.     with the exception of military agencies; (c) the code and/or
  26.     software based upon it may not be sold for a profit without
  27.     an explicit and specific permission from the author, except
  28.     that a minimal fee may be charged for media on which it is
  29.     copied, and for copying and handling; (d) the code must be 
  30.     distributed in the form in which it has been released by the
  31.     author; and (e) the code and software based upon it may not 
  32.     be used for illegal activities. 
  33.  
  34. ****************************************************************/
  35.  
  36. #include "stdio.h"
  37. #ifdef __STDC__
  38. #include "stdlib.h"
  39. #endif
  40.  
  41. #include "X11/Xlib.h"
  42. #include "X11/Xutil.h"
  43. #include "X11/keysym.h"
  44. #include "X11/keysymdef.h"
  45. #include "X11/cursorfont.h"
  46.  
  47. #include "bw.h"
  48. #include "kb.h"
  49. #include "gr.h"
  50.  
  51. #define IMAGES                  64
  52. #define KEY_NEEDED              FALSE
  53. #define    MAX_SCREEN_HEIGHT    500
  54. #define MAX_SCREEN_WIDTH        800
  55. #define X_OFFSET                 30
  56. #define Y_OFFSET                 30
  57. #define REQ_BORDER_WIDTH          3
  58. #define    EVENT_MASK              ( ButtonPressMask   | \
  59.                                   ButtonReleaseMask | \
  60.                                   KeyPressMask )
  61. #define KEYBUF_LENGTH            64
  62.  
  63. /****************************************************************
  64.  
  65.    The following globals are defined in the gr specification 
  66.    and are accessible to users of gr-based programs.  
  67.  
  68. ****************************************************************/
  69.  
  70. int   gr_screens = 2;
  71. int   gr_colors = 2;
  72. int   gr_pxsize = 30;
  73. int   gr_pysize = 30;
  74. int   gr_ismouse = TRUE;
  75. int   gr_blitting = TRUE;
  76. int   gr_clipping = FALSE;        /* Not yet */
  77. int   gr_saving = TRUE;
  78.  
  79. /****************************************************************
  80.  
  81.    The following globals are specific to the X Windows implementaion
  82.    of the gr standard and should not be accessible to users of 
  83.    gr-based programs.  
  84.  
  85. ****************************************************************/
  86.  
  87. struct gr_window      *grwind;          /* primary gr window */
  88. Display               *x_display;    /* primary X Windows display */
  89. Colormap              x_colormap;    /* system color map */
  90. XColor                rgbcolor, hardwarecolor;
  91. int                   x_screen;        /* which screen is in use */
  92. XSetWindowAttributes  x_windattributes; /* send requested attributes */
  93. XSizeHints            x_sizehints;      /* send size "hints" */
  94. unsigned long         x_windmask;       /* send window mask */
  95. Window                x_primary;        /* the principal X Window, used 
  96.                        when GR_PRIMARY is specified */
  97. Pixmap                x_hidden;         /* a second X Window, used 
  98.                        when GR_HIDDEN is specified */
  99. Drawable              x_selected;       /* X Drawable variable, which may be set
  100.                        to either x_primary or x_hidden */
  101. int                   x_mousevent;      /* is mouse event pending? */
  102. int                   x_keybevent;      /* is keyboard event pending? */
  103. int                   x_moxpos;         /* mouse x position pending */
  104. int                   x_moypos;         /* mouse y position pending */
  105. int                   x_keypending;     /* key pending */
  106. int                   x_depth;        /* depth (color planes ) */
  107. XFontStruct           *x_font10;     /* font structure: 10 y */
  108. XFontStruct           *x_font13;     /* font structure: 13 y */
  109. XFontStruct           *x_font15;     /* font structure: 15 y */
  110. XFontStruct           *x_font20;     /* font structure: 20 y */
  111. XFontStruct           *x_font31;     /* font structure: 31 y */
  112. XFontStruct           *x_curfont;       /* font struct in use */
  113. XGCValues             x_gcvals;         /* graphics content values */
  114. GC                    x_fontgc;       /* graphics context for font */
  115. GC                    x_drawgc;       /* graphics context for drawing */
  116. Cursor                x_cursor;         /* cursor to use for this X Window */
  117. Pixmap                x_stippm;         /* stipple pixmap */
  118.  
  119. char                  x_stipple[] = { 170, 85, 170, 85, 170, 85, 170, 85 };
  120. unsigned long         x_colchart[ 16 ];    /* chart of sixteen colors */
  121. extern unsigned long  x_color();    /* see function below */
  122. Pixmap                x_images[ IMAGES ]; /* images */
  123.  
  124. /****************************************************************
  125.  
  126.    gr_init()
  127.  
  128. ****************************************************************/
  129.  
  130. gr_init( window, path )
  131.    struct gr_window *window;
  132.    char *path;
  133.    {
  134.    int x_xsize, x_ysize;
  135.    int req_xsize, req_ysize;
  136.    register int i;
  137.    
  138.    /*    Part 1 of the Initialization:
  139.    **
  140.    **    Open and X Windows Display and Window and set system parameters
  141.    **    based on it.
  142.    */
  143.  
  144.    grwind = window;
  145.  
  146.    /* Open an X Windows display */ 
  147.  
  148.    x_display = XOpenDisplay( NULL );
  149.    
  150.    /* If the display is null, return */
  151.  
  152.    if ( x_display == NULL )
  153.       {
  154.       return FALSE;
  155.       }
  156.  
  157.    /* get the screen currently in use and some basic data */
  158.  
  159.    x_screen = DefaultScreen( x_display );
  160.    x_depth = DefaultDepth( x_display, x_screen );
  161.    x_colormap = DefaultColormap( x_display, x_screen );
  162.    x_xsize = DisplayWidth( x_display, x_screen );
  163.    x_ysize = DisplayHeight( x_display, x_screen );
  164.    
  165.    /* determine requested height and width of X Window */
  166.  
  167.    if ( x_xsize >= ( MAX_SCREEN_WIDTH + X_OFFSET ))
  168.       {
  169.       req_xsize = MAX_SCREEN_WIDTH;
  170.       }
  171.    else
  172.       {
  173.       req_xsize = x_xsize;
  174.       }
  175.  
  176.    if ( x_ysize >= ( MAX_SCREEN_HEIGHT + Y_OFFSET ))
  177.       {
  178.       req_ysize = MAX_SCREEN_HEIGHT;
  179.       }
  180.    else
  181.       {
  182.       req_ysize = x_ysize;
  183.       }
  184.  
  185.    /*   Set a cursor for this application */
  186.  
  187.    x_cursor = XCreateFontCursor( x_display, XC_left_ptr );
  188.  
  189.    /* set requested window attributes in structure to be passed */
  190.  
  191.    x_windattributes.border_pixel =
  192.       WhitePixel( x_display, x_screen );
  193.    x_windattributes.background_pixel =
  194.       BlackPixel( x_display, x_screen );
  195.    x_windattributes.cursor = x_cursor;
  196.    x_windmask = ( CWCursor | CWBackPixel | CWBorderPixel 
  197.       | CWOverrideRedirect );
  198.  
  199.    /* now create the window and hidden pixmap */
  200.  
  201.    x_primary = XCreateWindow( x_display, RootWindow( x_display, x_screen ),
  202.       X_OFFSET, Y_OFFSET, req_xsize, req_ysize, REQ_BORDER_WIDTH, x_depth,
  203.       InputOutput, CopyFromParent, x_windmask, &x_windattributes );
  204.  
  205.    x_hidden = XCreatePixmap( x_display, x_primary,
  206.       req_xsize, req_ysize, x_depth );
  207.  
  208.    x_selected = x_primary;
  209.  
  210.    /* Send size hints to the window manager */
  211.  
  212.    x_sizehints.flags  = USPosition | USSize;
  213.    x_sizehints.x      = X_OFFSET;
  214.    x_sizehints.y      = Y_OFFSET;
  215.    x_sizehints.width  = req_xsize;
  216.    x_sizehints.height = req_ysize;
  217.    XSetNormalHints( x_display, x_primary, &x_sizehints );
  218.  
  219.    /* Display the X Window */
  220.  
  221.    XMapRaised( x_display, x_primary );
  222.  
  223.    /* "Flush" the display to send all output to the screen */
  224.  
  225.    XFlush( x_display );
  226.  
  227.    /* Establish a graphics content for drawing */
  228.  
  229.    x_drawgc = XCreateGC( x_display, x_primary, (unsigned long) 0,
  230.       &x_gcvals );
  231.  
  232.    /* Set the stipple pattern for filling */
  233.  
  234.    x_stippm = XCreateBitmapFromData( x_display, x_primary, x_stipple, 8, 8 );
  235.    XSetStipple( x_display, x_drawgc, x_stippm );
  236.  
  237.    /* Set global gr variables based on this window */
  238.    
  239.    window->xmax = req_xsize;
  240.    window->ymax = req_ysize;
  241.  
  242.    /*    Part 2 of the Initialization:
  243.    **
  244.    **    Set a default font.
  245.    */
  246.  
  247.    x_font10 = XLoadQueryFont( x_display, "6x10" );
  248.    x_font13 = XLoadQueryFont( x_display, "8x13" );
  249.    x_font15 = XLoadQueryFont( x_display, "9x15" );
  250.    x_font20 = XLoadQueryFont( x_display, "vr-20" );
  251.    x_font31 = XLoadQueryFont( x_display, "vr-31" );
  252.    x_fontgc = XCreateGC( x_display, x_primary, (unsigned long) 0,
  253.       &x_gcvals );
  254.    XSetForeground( x_display, x_fontgc, WhitePixel( x_display, x_screen ));
  255.    XSetBackground( x_display, x_fontgc, BlackPixel( x_display, x_screen ));
  256.    XSetFont( x_display, x_fontgc, x_font13->fid );
  257.  
  258.    x_curfont = x_font13;
  259.    grwind->fysize = x_font13->ascent + x_font13->descent;
  260.    grwind->fxsize = XTextWidth( x_font13, "m", 1 );
  261.  
  262.    x_initcolor();        /* initialize color */
  263.  
  264.    /*   clear the screen */
  265.  
  266.    gr_cls( GR_PRIMARY );
  267.    gr_cls( GR_HIDDEN );
  268.    XFlush( x_display );
  269.  
  270.    /*    Part 3 of the Initialization:
  271.    **
  272.    **    Initialize X events so the keyboard and mouse imput can
  273.    **    be processed. 
  274.    */
  275.  
  276.    /* select input from key press, button press, and button release */   
  277.  
  278.    XSelectInput( x_display, x_primary, EVENT_MASK );
  279.  
  280.    /* set image buffer pointers to NULL */
  281.  
  282.    for ( i = 0; i < IMAGES; ++i )
  283.       {
  284.       x_images[ i ] = NULL;
  285.       }
  286.  
  287.    /* start out at null state for keyboard and mouse entries */
  288.  
  289.    x_mousevent = FALSE;
  290.    x_keybevent = FALSE;
  291.    x_pollevent();
  292.  
  293.    window->initialized = grwind->initialized = TRUE;
  294.  
  295. #if    KEY_NEEDED
  296.    kb_rx();
  297. #endif
  298.    return TRUE;
  299.    }
  300.  
  301. /****************************************************************
  302.  
  303.    gr_deinit()
  304.  
  305. ****************************************************************/
  306.  
  307. gr_deinit( screen )
  308.    int screen;
  309.    {
  310.  
  311.    /* remove the X Window */
  312.  
  313.    XDestroyWindow( x_display, x_primary );
  314.    XFreePixmap( x_display, x_hidden );
  315.    
  316.    /* close the X Display */
  317.  
  318.    XCloseDisplay( x_display );
  319.  
  320.    }
  321.  
  322. /****************************************************************
  323.  
  324.    gr_cls()
  325.  
  326. ****************************************************************/
  327.  
  328. gr_cls( screen )
  329.    int screen;
  330.    {
  331.    if ( screen == GR_PRIMARY )
  332.       {
  333.       XClearWindow( x_display, x_primary );
  334.       }
  335.    else
  336.       {
  337.       gr_rectangle( GR_HIDDEN, 0, 0, grwind->xmax - 1, grwind->ymax - 1,
  338.          BLACK, SOLID );
  339.       }
  340.    XFlush( x_display );
  341.    }
  342.  
  343.  
  344. /****************************************************************
  345.  
  346.    gr_pixel()
  347.  
  348. ****************************************************************/
  349.  
  350. gr_pixel( screen, x, y, color )
  351.    int screen;
  352.    int x, y;
  353.    int color;
  354.    {
  355.  
  356. #ifdef  DEBUG
  357.    if ( ( x < 0 ) || ( x > grwind->xmax ))
  358.       {
  359.       sprintf( bw_ebuf, "[pr:] gr_pixel(): x value is %d", x );
  360.       bw_error( bw_ebuf );
  361.       return BW_ERROR;
  362.       }
  363.    if ( ( y < 0 ) || ( y > grwind->ymax ))
  364.       {
  365.       sprintf( bw_ebuf, "[pr:] gr_pixel(): y value is %d", y );
  366.       bw_error( bw_ebuf );
  367.       return BW_ERROR;
  368.       }
  369. #endif
  370.  
  371.    x_setscreen( screen );
  372.    XSetForeground( x_display, x_drawgc, x_color( color ) );
  373.    XDrawPoint( x_display, x_selected, x_drawgc, x, grwind->ymax - y );
  374.    XFlush( x_display );
  375.    }
  376.          
  377. /****************************************************************
  378.  
  379.    gr_line()
  380.  
  381. ****************************************************************/
  382.  
  383. gr_line( screen, x1, y1, x2, y2, color, style )
  384.    int screen;
  385.    int x1, y1, x2, y2;
  386.    int color, style;
  387.    {
  388.  
  389. #ifdef  DEBUG
  390.    if ( ( x1 < 0 ) || ( x1 > grwind->xmax ))
  391.       {
  392.       sprintf( bw_ebuf, "[pr:] gr_line(): x1 value is %d", x1 );
  393.       bw_error( bw_ebuf );
  394.       return BW_ERROR;
  395.       }
  396.    if ( ( x2 < 0 ) || ( x2 > grwind->xmax ))
  397.       {
  398.       sprintf( bw_ebuf, "[pr:] gr_line(): x2 value is %d", x2 );
  399.       bw_error( bw_ebuf );
  400.       return BW_ERROR;
  401.       }
  402.    if ( ( y1 < 0 ) || ( y1 > grwind->ymax ))
  403.       {
  404.       sprintf( bw_ebuf, "[pr:] gr_line(): y1 value is %d", y1 );
  405.       bw_error( bw_ebuf );
  406.       return BW_ERROR;
  407.       }
  408.    if ( ( y2 < 0 ) || ( y2 > grwind->ymax ))
  409.       {
  410.       sprintf( bw_ebuf, "[pr:] gr_line(): y2 value is %d", y2 );
  411.       bw_error( bw_ebuf );
  412.       return BW_ERROR;
  413.       }
  414. #endif
  415.  
  416.    x_setscreen( screen );
  417.    XSetLineAttributes( x_display, x_drawgc, (unsigned) 1, 
  418.       x_linestyle( style ), 
  419.       CapNotLast, JoinMiter );
  420.    XSetForeground( x_display, x_drawgc, x_color( color ) );
  421.    XDrawLine( x_display, x_selected, x_drawgc, x1, grwind->ymax - y1, 
  422.       x2, grwind->ymax - y2 );
  423.    XFlush( x_display );
  424.    }
  425.  
  426. /****************************************************************
  427.  
  428.    gr_text()
  429.  
  430. ****************************************************************/
  431.  
  432. gr_text( screen, x, y, string, foreground, background )
  433.    int screen;
  434.    int x, y;
  435.    int foreground, background;
  436.    char *string;
  437.    {
  438.  
  439. #ifdef  DEBUG
  440.    if ( ( x < 0 ) || ( x > grwind->xmax ))
  441.       {
  442.       fprintf( stderr, "ERROR: [pr:] gr_text(): x value is %d", x );
  443.       kb_rx();
  444.       return BW_ERROR;
  445.       }
  446.    if ( ( y < 0 ) || ( y > grwind->ymax ))
  447.       {
  448.       fprintf( stderr, "ERROR: [pr:] gr_text(): y value is %d", y );
  449.       kb_rx();
  450.       return BW_ERROR;
  451.       }
  452. #endif
  453.  
  454.    x_setscreen( screen );
  455.  
  456.    XSetForeground( x_display, x_fontgc, x_color( foreground ) );
  457.    XSetBackground( x_display, x_fontgc, x_color( background ) );
  458.  
  459.    XDrawImageString( x_display, x_selected, x_fontgc, x, 
  460.       grwind->ymax - ( y + x_curfont->descent ), string,
  461.       strlen( string) );
  462.    XFlush( x_display );
  463.    }
  464.  
  465. /****************************************************************
  466.  
  467.    gr_strlen()
  468.  
  469. ****************************************************************/
  470.  
  471. unsigned int
  472. gr_strlen( string )
  473.    char *string;
  474.    {
  475.    return XTextWidth( x_curfont, string, strlen( string ) );
  476.    }
  477.  
  478. /****************************************************************
  479.  
  480.    gr_rectangle()
  481.  
  482. ****************************************************************/
  483.  
  484. gr_rectangle( screen, x1, y1, x2, y2, color, style )
  485.    int screen;
  486.    int x1, y1, x2, y2;
  487.    int color, style;
  488.    {
  489.  
  490. #ifdef  DEBUG
  491.    if ( ( x1 < 0 ) || ( x1 > grwind->xmax ))
  492.       {
  493.       sprintf( bw_ebuf, "[pr:] gr_rectangle(): x1 value is %d", x1 );
  494.       bw_error( bw_ebuf );
  495.       return BW_ERROR;
  496.       }
  497.    if ( ( x2 < 0 ) || ( x2 > grwind->xmax ))
  498.       {
  499.       sprintf( bw_ebuf, "[pr:] gr_rectangle(): x2 value is %d", x2 );
  500.       bw_error( bw_ebuf );
  501.       return BW_ERROR;
  502.       }
  503.    if ( ( y1 < 0 ) || ( y1 > grwind->ymax ))
  504.       {
  505.       sprintf( bw_ebuf, "[pr:] gr_rectangle(): y1 value is %d", y1 );
  506.       bw_error( bw_ebuf );
  507.       return BW_ERROR;
  508.       }
  509.    if ( ( y2 < 0 ) || ( y2 > grwind->ymax ))
  510.       {
  511.       sprintf( bw_ebuf, "[pr:] gr_rectangle(): y2 value is %d", y2 );
  512.       bw_error( bw_ebuf );
  513.       return BW_ERROR;
  514.       }
  515. #endif
  516.  
  517.    x_setscreen( screen );
  518.  
  519.    if ( style == HOLLOW )
  520.       {
  521.       XSetLineAttributes( x_display, x_drawgc, (unsigned int) 1,
  522.          LineSolid, CapNotLast, JoinMiter );
  523.       XSetForeground( x_display, x_drawgc, x_color( color ) );
  524.       XDrawRectangle( x_display, x_selected, x_drawgc, 
  525.          x1, grwind->ymax - y2, x2 - x1, y2 - y1 );
  526.       }
  527.    else
  528.       {
  529.       XSetFillRule( x_display, x_drawgc, EvenOddRule );
  530.       XSetFillStyle( x_display, x_drawgc, x_fillstyle( style ) );
  531.       XSetForeground( x_display, x_drawgc, x_color( color ) );
  532.       XSetBackground( x_display, x_drawgc, x_color( BLACK ) );
  533.       XFillRectangle( x_display, x_selected, x_drawgc, 
  534.          x1, grwind->ymax - y2, x2 - x1, y2 - y1 );
  535.       }
  536.    XFlush( x_display );
  537.    }
  538.  
  539. /****************************************************************
  540.  
  541.    gr_circle()
  542.  
  543. ****************************************************************/
  544.  
  545. gr_circle( screen, x, y, radius, color, style )
  546.    int screen;
  547.    int x, y, radius;
  548.    int color, style;
  549.    {
  550.  
  551. #ifdef  DEBUG
  552.    if ( ( x < 0 ) || ( x > grwind->xmax ))
  553.       {
  554.       sprintf( bw_ebuf, "[pr:] gr_circle(): x value is %d", x );
  555.       bw_error( bw_ebuf );
  556.       return BW_ERROR;
  557.       }
  558.    if ( ( y < 0 ) || ( y > grwind->ymax ))
  559.       {
  560.       sprintf( bw_ebuf, "[pr:] gr_circle(): y value is %d", y );
  561.       bw_error( bw_ebuf );
  562.       return BW_ERROR;
  563.       }
  564. #endif
  565.  
  566.    x_setscreen( screen );
  567.  
  568.    if ( style == HOLLOW )
  569.       {
  570.       XSetLineAttributes( x_display, x_drawgc, (unsigned int) 1,
  571.          LineSolid, CapNotLast, JoinMiter );
  572.       XSetForeground( x_display, x_drawgc, x_color( color ) );
  573.       XDrawArc( x_display, x_selected, x_drawgc, 
  574.          x - radius, ( grwind->ymax - y ) - radius, radius * 2, radius * 2,
  575.          0, 360 * 64 );
  576.       }
  577.    else
  578.       {
  579.       XSetFillRule( x_display, x_drawgc, EvenOddRule );
  580.       XSetFillStyle( x_display, x_drawgc, x_fillstyle( style ) );
  581.       XSetForeground( x_display, x_drawgc, x_color( color ) );
  582.       XSetBackground( x_display, x_drawgc, x_color( BLACK ) ); 
  583.       XFillArc( x_display, x_selected, x_drawgc, 
  584.          x - radius, ( grwind->ymax - y ) - radius, radius * 2, radius * 2,
  585.          0, 360 * 64 );
  586.       }
  587.    XFlush( x_display );
  588.    }
  589.  
  590. /****************************************************************
  591.  
  592.    gr_ellipse()
  593.  
  594. ****************************************************************/
  595.  
  596. gr_ellipse( screen, x, y, x_radius, y_radius, mode, color, style )
  597.    int screen;
  598.    int x, y, x_radius, y_radius;
  599.    int mode, color, style;
  600.    {
  601.    }
  602.          
  603. /****************************************************************
  604.  
  605.    gr_clip()
  606.  
  607. ****************************************************************/
  608.  
  609. gr_clip( screen, mode, x1, y1, x2, y2 )
  610.    int screen;
  611.    int mode;
  612.    int x1, y1, x2, y2;
  613.    {
  614.  
  615. #ifdef  DEBUG
  616.    if ( ( x1 < 0 ) || ( x1 > grwind->xmax ))
  617.       {
  618.       sprintf( bw_ebuf, "[pr:] gr_clip(): x1 value is %d", x1 );
  619.       bw_error( bw_ebuf );
  620.       return BW_ERROR;
  621.       }
  622.    if ( ( x2 < 0 ) || ( x2 > grwind->xmax ))
  623.       {
  624.       sprintf( bw_ebuf, "[pr:] gr_clip(): x2 value is %d", x2 );
  625.       bw_error( bw_ebuf );
  626.       return BW_ERROR;
  627.       }
  628.    if ( ( y1 < 0 ) || ( y1 > grwind->ymax ))
  629.       {
  630.       sprintf( bw_ebuf, "[pr:] gr_clip(): y1 value is %d", y1 );
  631.       bw_error( bw_ebuf );
  632.       return BW_ERROR;
  633.       }
  634.    if ( ( y2 < 0 ) || ( y2 > grwind->ymax ))
  635.       {
  636.       sprintf( bw_ebuf, "[pr:] gr_clip(): y2 value is %d", y2 );
  637.       bw_error( bw_ebuf );
  638.       return BW_ERROR;
  639.       }
  640. #endif
  641.  
  642.    }
  643.  
  644. /****************************************************************
  645.  
  646.    gr_font()
  647.  
  648. ****************************************************************/
  649.  
  650. gr_font( screen, type, rq_height )
  651.    int screen;
  652.    int type, rq_height;
  653.    {
  654.    XFontStruct *oldfont;
  655.  
  656.    oldfont = x_curfont;
  657.  
  658.    if ( rq_height > 25 )
  659.       {
  660.       x_curfont = x_font31;
  661.       }
  662.    else if ( rq_height > 17 )
  663.       {
  664.       x_curfont = x_font20;
  665.       }
  666.    else if ( rq_height > 14 )
  667.       {
  668.       x_curfont = x_font15;
  669.       }
  670.    else if ( rq_height > 11 )
  671.       {
  672.       x_curfont = x_font13;
  673.       }
  674.    else 
  675.       {
  676.       x_curfont = x_font10;
  677.       }
  678.       
  679.    if ( ( x_curfont == NULL ) || ( x_curfont->fid == 0 ))
  680.       {
  681.       x_curfont = oldfont;
  682.       }
  683.  
  684.    XSetFont( x_display, x_fontgc, x_curfont->fid );
  685.    grwind->fysize = x_curfont->ascent + x_curfont->descent;
  686.    grwind->fxsize = XTextWidth( x_curfont, "m", 1 );
  687.  
  688.    }
  689.  
  690. /****************************************************************
  691.  
  692.     gr_blit()
  693.  
  694. ****************************************************************/
  695.  
  696. gr_blit( src, dst, x1, y1, x2, y2 )
  697.    int src, dst;
  698.    int x1, y1, x2, y2;
  699.    {
  700.  
  701. #ifdef  DEBUG
  702.    if ( ( x1 < 0 ) || ( x1 > grwind->xmax ))
  703.       {
  704.       sprintf( bw_ebuf, "[pr:] gr_blit(): x1 value is %d", x1 );
  705.       bw_error( bw_ebuf );
  706.       return BW_ERROR;
  707.       }
  708.    if ( ( x2 < 0 ) || ( x2 > grwind->xmax ))
  709.       {
  710.       sprintf( bw_ebuf, "[pr:] gr_blit(): x2 value is %d", x2 );
  711.       bw_error( bw_ebuf );
  712.       return BW_ERROR;
  713.       }
  714.    if ( ( y1 < 0 ) || ( y1 > grwind->ymax ))
  715.       {
  716.       sprintf( bw_ebuf, "[pr:] gr_blit(): y1 value is %d", y1 );
  717.       bw_error( bw_ebuf );
  718.       return BW_ERROR;
  719.       }
  720.    if ( ( y2 < 0 ) || ( y2 > grwind->ymax ))
  721.       {
  722.       sprintf( bw_ebuf, "[pr:] gr_blit(): y2 value is %d", y2 );
  723.       bw_error( bw_ebuf );
  724.       return BW_ERROR;
  725.       }
  726.    if ( src == dst )
  727.       {
  728.       sprintf( bw_ebuf, "[pr:] gr_blit(): src == dst" );
  729.       bw_error( bw_ebuf );
  730.       return BW_ERROR;
  731.       }
  732. #endif
  733.  
  734.    if ( src == GR_HIDDEN )
  735.       {
  736.       XCopyArea( x_display, x_hidden, x_primary, x_drawgc,
  737.          x1, grwind->ymax - y2, x2 - x1, y2 - y1, x1, grwind->ymax - y2 );
  738.       }
  739.  
  740.    else
  741.       {
  742.       XCopyArea( x_display, x_primary, x_hidden, x_drawgc,
  743.          x1, grwind->ymax - y2, x2 - x1, y2 - y1, x1, grwind->ymax - y2 );
  744.       }
  745.  
  746.    }
  747.  
  748. /****************************************************************
  749.  
  750.    gr_imsave()
  751.  
  752. ****************************************************************/
  753.  
  754. gr_imsave( screen, mode, x1, y1, x2, y2, image )
  755.    int screen; 
  756.    int mode, x1, y1, x2, y2;
  757.    int *image;
  758.    {
  759.    register int r;
  760.    int carry_on;
  761.  
  762. #ifdef  DEBUG
  763.    if ( ( x1 < 0 ) || ( x1 > grwind->xmax ))
  764.       {
  765.       sprintf( bw_ebuf, "[pr:] gr_save(): x1 value is %d", x1 );
  766.       bw_error( bw_ebuf );
  767.       return BW_ERROR;
  768.       }
  769.    if ( ( x2 < 0 ) || ( x2 > grwind->xmax ))
  770.       {
  771.       sprintf( bw_ebuf, "[pr:] gr_save(): x2 value is %d", x2 );
  772.       bw_error( bw_ebuf );
  773.       return BW_ERROR;
  774.       }
  775.    if ( ( y1 < 0 ) || ( y1 > grwind->ymax ))
  776.       {
  777.       sprintf( bw_ebuf, "[pr:] gr_save(): y1 value is %d", y1 );
  778.       bw_error( bw_ebuf );
  779.       return BW_ERROR;
  780.       }
  781.    if ( ( y2 < 0 ) || ( y2 > grwind->ymax ))
  782.       {
  783.       sprintf( bw_ebuf, "[pr:] gr_save(): y2 value is %d", y2 );
  784.       bw_error( bw_ebuf );
  785.       return BW_ERROR;
  786.       }
  787. #endif
  788.  
  789.    x_setscreen( screen );
  790.  
  791.    /* mode == TRUE, save the area */
  792.  
  793.    if ( mode == TRUE )
  794.       {
  795.  
  796.       /* find an available slot */
  797.  
  798.       carry_on = TRUE;
  799.       r = 0;
  800.       while( ( carry_on == TRUE ) && ( r < IMAGES ) )
  801.      {
  802.      if ( x_images[ r ] == NULL )
  803.         {
  804.         carry_on = FALSE;
  805.         }
  806.      else
  807.         {
  808.         ++r;
  809.         }
  810.      }
  811.  
  812.       if ( r >= IMAGES )
  813.      {
  814.      bw_error( "No more slots for image storage" );
  815.      return FALSE;
  816.      }
  817.  
  818.       *image = r;
  819.  
  820.       /* create a new pixmap */
  821.  
  822.       x_images[ *image ] = XCreatePixmap( x_display, x_selected,
  823.      ( x2 - x1 ) + 1, ( y2 - y1 ) + 1, x_depth );
  824.  
  825.       /* copy the area */
  826.  
  827.       XCopyArea( x_display, x_selected, x_images[ *image ], x_drawgc,
  828.          x1, grwind->ymax - y2, x2 - x1, y2 - y1, 0, 0 );
  829.       }
  830.  
  831.    /* mode == FALSE, restore the area */
  832.  
  833.    else
  834.       {
  835.       XCopyArea( x_display, x_images[ *image ], x_selected, x_drawgc,
  836.          0, 0, x2 - x1, y2 - y1, x1, grwind->ymax - y2 );
  837.       }
  838.    }
  839.  
  840. /****************************************************************
  841.  
  842.    gr_imfree()
  843.  
  844. ****************************************************************/
  845.  
  846. gr_imfree( image )
  847.    int image;
  848.    {
  849.    XFreePixmap( x_display, x_images[ image ] );
  850.    x_images[ image ] = NULL;
  851.    }
  852.  
  853. /****************************************************************
  854.  
  855.    gr_mouse()
  856.  
  857. ****************************************************************/
  858.  
  859. gr_mouse( mode, x, y, buttons )
  860.    int mode;
  861.    int *x, *y;
  862.    int *buttons;
  863.    {
  864.  
  865.    switch ( mode )
  866.       {
  867.       case STATUS:
  868.       case SAMPLE:
  869.          if ( x_mousevent == TRUE )
  870.             {
  871.             *x = x_moxpos;
  872.             *y = grwind->ymax - x_moypos;
  873.             return TRUE;
  874.             }
  875.          x_pollevent();
  876.          if ( x_mousevent == TRUE )
  877.             {
  878.             *x = x_moxpos;
  879.             *y = grwind->ymax - x_moypos;
  880.             return TRUE;
  881.             }
  882.          return FALSE;
  883.          break;
  884.       
  885.       case WAIT:
  886.          while( x_mousevent == FALSE )
  887.             {
  888.             x_pollevent();
  889.             }
  890.          x_mousevent = FALSE;
  891.          *x = x_moxpos;
  892.          *y = grwind->ymax - x_moypos;
  893.          break;
  894.          
  895.       }
  896.  
  897.    }
  898.  
  899. /****************************************************************
  900.  
  901.    x_pollevent()
  902.  
  903. ****************************************************************/
  904.  
  905. x_pollevent()
  906.    {
  907.    static XEvent x_event;
  908.    static XComposeStatus x_cstatus;
  909.    static KeySym x_keysym;
  910.    static int x_keybufmaxlen = KEYBUF_LENGTH - 1;
  911.    static char x_keybuf[ KEYBUF_LENGTH ];
  912.    int length;
  913.   
  914. #ifdef OLD_DEBUG
  915.    fprintf( stderr, "Polling...\n" );
  916. #endif
  917.  
  918.    /* poll X Window to see if there is an event */
  919.  
  920.    if ( XCheckMaskEvent( x_display, (unsigned long) EVENT_MASK, &x_event ) 
  921.       == True )
  922.       {
  923.       switch ( x_event.type )
  924.          {
  925.          case ButtonPress:
  926.          case ButtonRelease:
  927. #ifdef OLD_DEBUG
  928.             fprintf( stderr, "Mouse event...\n" );
  929. #endif
  930.             x_mousevent = TRUE;
  931.             x_moxpos    = x_event.xbutton.x;
  932.             x_moypos    = x_event.xbutton.y;
  933.             break;
  934.          case KeyPress:
  935. #ifdef OLD_DEBUG
  936.             fprintf( stderr, "Keyboard event...\n" );
  937. #endif
  938.             x_keybevent  = TRUE;
  939.             length = XLookupString( &x_event, x_keybuf, x_keybufmaxlen, 
  940.                &x_keysym,
  941.                &x_cstatus );
  942.             if ( ( x_keysym >= ' ' ) && ( x_keysym <= '~' )
  943.                && ( length > 0 ))
  944.                {
  945.                x_keypending = x_keysym;
  946.                }
  947.             else
  948.                {
  949.                switch( x_keysym )
  950.                   {
  951.                   case XK_Return:
  952.                      x_keypending = '\r';
  953.                      break;
  954.                   case XK_BackSpace:
  955.                      x_keypending = '\010';
  956.                      break;
  957.                   case XK_Escape:
  958.                      x_keypending = '\033';
  959.                      break;
  960.                   case XK_Delete:
  961.                      x_keypending = KB_DELETE;
  962.                      break;
  963.                   case XK_Up:
  964.                      x_keypending = KB_UP;
  965.                      break;
  966.                   case XK_Down:
  967.                      x_keypending = KB_DOWN;
  968.                      break;
  969.                   case XK_Right:
  970.                      x_keypending = KB_RIGHT;
  971.                      break;
  972.                   case XK_Left:
  973.                      x_keypending = KB_LEFT;
  974.                      break;
  975.                   case XK_F1:
  976.                      x_keypending = KB_FK1;
  977.                      break;
  978.                   case XK_F2:
  979.                      x_keypending = KB_FK2;
  980.                      break;
  981.                   case XK_F3:
  982.                      x_keypending = KB_FK3;
  983.                      break;
  984.                   default:
  985.                      x_keypending = 0;
  986.                      break;
  987.                   }
  988.                }
  989.             break;
  990.          }      
  991.       return TRUE;
  992.       }
  993.  
  994.    return FALSE;
  995.       
  996.    }
  997.  
  998. /****************************************************************
  999.  
  1000.    x_initcolor()
  1001.  
  1002. ****************************************************************/
  1003.  
  1004. x_initcolor()
  1005.    {
  1006.    
  1007.    if ( x_depth <= 1 )
  1008.       {
  1009.       return FALSE;
  1010.       }
  1011.  
  1012.    gr_colors = 16;
  1013.  
  1014.    XLookupColor( x_display, x_colormap, "Black", &rgbcolor, &hardwarecolor );
  1015.    XAllocColor( x_display, x_colormap, &hardwarecolor );
  1016.    x_colchart[ BLACK ] = hardwarecolor.pixel;
  1017.    
  1018.    XLookupColor( x_display, x_colormap, "White", &rgbcolor, &hardwarecolor );
  1019.    XAllocColor( x_display, x_colormap, &hardwarecolor );
  1020.    x_colchart[ WHITE ] = hardwarecolor.pixel;
  1021.    
  1022.    XLookupColor( x_display, x_colormap, "Red", &rgbcolor, &hardwarecolor );
  1023.    XAllocColor( x_display, x_colormap, &hardwarecolor );
  1024.    x_colchart[ LIGHT_RED ] = hardwarecolor.pixel;
  1025.    x_colchart[ DARK_RED ] = hardwarecolor.pixel;
  1026.    
  1027.    XLookupColor( x_display, x_colormap, "Green", &rgbcolor, &hardwarecolor );
  1028.    XAllocColor( x_display, x_colormap, &hardwarecolor );
  1029.    x_colchart[ LIGHT_GREEN ] = hardwarecolor.pixel;
  1030.    x_colchart[ DARK_GREEN ] = hardwarecolor.pixel;
  1031.  
  1032.    XLookupColor( x_display, x_colormap, "Blue", &rgbcolor, &hardwarecolor );
  1033.    XAllocColor( x_display, x_colormap, &hardwarecolor );
  1034.    x_colchart[ LIGHT_BLUE ] = hardwarecolor.pixel;
  1035.    x_colchart[ DARK_BLUE ] = hardwarecolor.pixel;
  1036.  
  1037.    XLookupColor( x_display, x_colormap, "Yellow", &rgbcolor, &hardwarecolor );
  1038.    XAllocColor( x_display, x_colormap, &hardwarecolor );
  1039.    x_colchart[ LIGHT_YELLOW ] = hardwarecolor.pixel;
  1040.    x_colchart[ DARK_YELLOW ] = hardwarecolor.pixel;
  1041.  
  1042.    XLookupColor( x_display, x_colormap, "Cyan", &rgbcolor, &hardwarecolor );
  1043.    XAllocColor( x_display, x_colormap, &hardwarecolor );
  1044.    x_colchart[ LIGHT_CYAN ] = hardwarecolor.pixel;
  1045.    x_colchart[ DARK_CYAN ] = hardwarecolor.pixel;
  1046.  
  1047.    XLookupColor( x_display, x_colormap, "Magenta", &rgbcolor, &hardwarecolor );
  1048.    XAllocColor( x_display, x_colormap, &hardwarecolor );
  1049.    x_colchart[ LIGHT_MAGENTA ] = hardwarecolor.pixel;
  1050.    x_colchart[ DARK_MAGENTA ] = hardwarecolor.pixel;
  1051.  
  1052.    return TRUE;
  1053.    }
  1054.  
  1055. /****************************************************************
  1056.  
  1057.    x_color()
  1058.  
  1059. ****************************************************************/
  1060.  
  1061. unsigned long
  1062. x_color( gr_color )
  1063.    int gr_color;
  1064.    {
  1065.  
  1066.  
  1067.    if ( x_depth <= 1 )
  1068.       {
  1069.       switch ( gr_color )
  1070.          {
  1071.          case WHITE:
  1072.             return WhitePixel( x_display, x_screen );
  1073.             break;
  1074.          case BLACK:
  1075.          default:
  1076.             return BlackPixel( x_display, x_screen );
  1077.             break;
  1078.          }
  1079.       }
  1080.  
  1081.    else
  1082.       {
  1083.       return x_colchart[ gr_color ];
  1084.       }
  1085.    }
  1086.  
  1087. /****************************************************************
  1088.  
  1089.    x_fillstyle()
  1090.  
  1091. ****************************************************************/
  1092.  
  1093. x_fillstyle( gr_fillstyle )
  1094.    int gr_fillstyle;
  1095.    {
  1096.    switch( gr_fillstyle )
  1097.       {
  1098.       case GRID:
  1099.          return FillStippled;
  1100.          break;
  1101.       case HATCH:
  1102.          return FillTiled;
  1103.          break;
  1104.       case HOLLOW:
  1105.       case SOLID:
  1106.       default:
  1107.          return FillSolid;
  1108.          break;
  1109.       } 
  1110.    }
  1111.  
  1112. /****************************************************************
  1113.  
  1114.    x_linestyle()
  1115.  
  1116. ****************************************************************/
  1117.  
  1118. x_linestyle( gr_linestyle )
  1119.    int gr_linestyle;
  1120.    {
  1121.    switch( gr_linestyle )
  1122.       {
  1123.       case GRID:
  1124.          return LineOnOffDash;
  1125.          break;
  1126.       case SOLID:
  1127.       case HOLLOW:
  1128.       default:
  1129.          return LineSolid;
  1130.          break;
  1131.       }
  1132.    }
  1133.  
  1134. /****************************************************************
  1135.  
  1136.    x_setscreen()
  1137.  
  1138. ****************************************************************/
  1139.  
  1140. x_setscreen( screen )
  1141.    int screen;
  1142.    {
  1143.    switch( screen )
  1144.       {
  1145.       case GR_PRIMARY:
  1146.          x_selected = (Drawable) x_primary;
  1147.          break;
  1148.       case GR_HIDDEN:
  1149.          x_selected = (Drawable) x_hidden;
  1150.          break;
  1151.       default:
  1152. #ifdef DEBUG
  1153.          sprintf( bw_ebuf, "[pr:] x_screen received %d", screen );
  1154.          bw_error( bw_ebuf );
  1155. #endif
  1156.          return BW_ERROR;
  1157.          break;
  1158.       }
  1159.    return TRUE;
  1160.    }
  1161.  
  1162.  
  1163.